﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using CarParkBooking.DAL;

namespace CarParkBooking.Models
{
    public class BookCalendarModel
    {
        public bool CanBook { get; set; }
        public bool CanCancel { get; set; }
        public bool IsValidDate { get; set; }
        public bool IsBookedByYourself { get; set; }
        public DateTime BookDate { get; set; }
        public Int32 RemainingBookSpaces { get; set; }
        public IList<string> BookedUsers { get; set; }

        public static BookCalendarModel GetModelByCarParkAndBookDate(int selectedCarParkId, DateTime bookDate, string userName)
        {
            CarParkDataContext _dataContext = new CarParkDataContext();
            var selectedCarPark =
                (from c in _dataContext.CarParks
                 where c.ID == selectedCarParkId
                 select c).First();


            var bookCalendarModel = new BookCalendarModel();
            var bookedSpacesPerDay =
                (from b in _dataContext.Bookings
                where b.BookedDate.Value == bookDate && b.CarParkID == selectedCarParkId
                select b).ToList();

                //bookedSpacesInMonth.Where(x => x.Key.Value == currentDate).Select(x => x.BookedSpaces).FirstOrDefault();
            if (bookedSpacesPerDay == null)
            {
                bookedSpacesPerDay = new List<Booking>();
            }

            bookCalendarModel.CanBook = true;
            bookCalendarModel.CanCancel = true;
            bookCalendarModel.BookDate = bookDate;
            bookCalendarModel.RemainingBookSpaces = selectedCarPark.MaxSlotPerDay.Value - bookedSpacesPerDay.Count();
            bookCalendarModel.BookedUsers = (from b in bookedSpacesPerDay select b.UserName).ToList();
            bookCalendarModel.IsBookedByYourself = bookCalendarModel.BookedUsers.Contains(userName);
            bookCalendarModel.IsValidDate = bookCalendarModel.BookDate >= DateTime.Today;

            // get remaining slot of current user in this month
            var bookedSpacesOfCurrentUserInMonth =
                from b in _dataContext.Bookings
                where b.UserName.Equals(userName)
                select b;

            // determine whether the current user can cancel CarPark Booking
            if (bookDate < DateTime.Today || bookCalendarModel.IsBookedByYourself == false)
            {
                bookCalendarModel.CanCancel = false;
            }

            // determine whether the current user can book CarPark
            if (bookedSpacesPerDay.Count() == selectedCarPark.MaxSlotPerDay
                || bookedSpacesOfCurrentUserInMonth.Count() == selectedCarPark.MaxSlotPerMonth
                || bookDate < DateTime.Today
                || bookCalendarModel.CanCancel)
            {
                bookCalendarModel.CanBook = false;
            }

            return bookCalendarModel;
        }

        public static BookCalendarModel BookForUser(int selectedCarParkId, DateTime bookDate, string userName)
        {
            CarParkDataContext _dataContext = new CarParkDataContext();

            var bookCalendarModel = GetModelByCarParkAndBookDate(selectedCarParkId, bookDate, userName);

            var currentBookingQuery =
                from b in _dataContext.Bookings
                where b.CarParkID == selectedCarParkId && b.BookedDate.Value == bookDate && b.UserName.Equals(userName)
                select b;

            if (bookCalendarModel.CanBook)
            { 
                var currentBooking = new Booking(){
                    CarParkID = selectedCarParkId
                    , BookedDate = bookDate
                    , UserName = userName
                };

                _dataContext.Bookings.InsertOnSubmit(currentBooking);
                _dataContext.SubmitChanges();

                // refresh data for Book Calendar Model
                bookCalendarModel = GetModelByCarParkAndBookDate(selectedCarParkId, bookDate, userName);
            }

            return bookCalendarModel;
        }

        public static BookCalendarModel CancelBookingForUser(int selectedCarParkId, DateTime bookDate, string userName)
        {
            CarParkDataContext _dataContext = new CarParkDataContext();
            var currentBookingQuery =
                from b in _dataContext.Bookings
                where b.CarParkID == selectedCarParkId && b.BookedDate.Value == bookDate && b.UserName.Equals(userName)
                select b;

            if (currentBookingQuery.Count() > 0)
            {
                _dataContext.Bookings.DeleteOnSubmit(currentBookingQuery.Single());
                _dataContext.SubmitChanges();
            }
            
            var bookCalendarModel = GetModelByCarParkAndBookDate(selectedCarParkId, bookDate, userName);

            return bookCalendarModel;
        }
    }
}